﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace ENG.PSSAirbusSoundExtender
{
  static class PSS
  {
    #region Fields & Properties

    private static List<ASystem> AS = new List<ASystem>();
    private static Dictionary<ASystem, Process> Procs = new Dictionary<ASystem, Process>();

    #endregion Fields & Properties

    #region Public methods

    public static void StartUp (List<ASystem> systems)
    {
      if (systems == null)
        throw new ArgumentNullException();

      ShutDown();
      Procs.Clear();

      AS = systems;

      foreach (var fItem in AS)
      {
        fItem.IsOnChanged += new ASystem.IsOnChangedHandler(system_IsOnChanged);

        Procs.Add(fItem, null);
      } // foreach (var fItem in AS)

      Refresh();
    }

    public static void ShutDown()
    {
      foreach (var fItem in Procs.Values)
      {
        if ((fItem != null) && (!fItem.HasExited))
          fItem.Kill();
      } // foreach (var fItem in Procs.Values)
    }

    #endregion Public methods

    #region Private methods

    private static void system_IsOnChanged(ASystem sender)
    {
      Refresh();
    }

    public static List<ASystem> GetSystems()
    {
      return AS;
    }

    public static void ProceedClick(System.Drawing.Point point)
    {
      foreach (var fItem in AS)
      {
        fItem.TrySwitch(point);
      } // foreach (var fItem in ASystems)
    }

    public static void SwitchSystem(ASystem system)
    {
      system.Switch();

      Refresh();
    }

    private static void Refresh()
    {
      List<ASystem> run = new List<ASystem>();
      List<ASystem> norun = new List<ASystem>();

      int battOnCount = 0;

      foreach (var fItem in AS)
      {
        if (fItem.IsBattery && fItem.IsOn)
          battOnCount += 1;
      }

      foreach (var fItem in AS)
      {
        if (fItem.IsBattery)
        {
          if (fItem.IsOn)
            fItem.Status = ASystem.eStatus.On;
          else
            fItem.Status = ASystem.eStatus.Off;
        }
        else
        {
          if (fItem.IsOn)
          {
            if (fItem.MinBatteryCountToRun <= battOnCount)
              fItem.Status = ASystem.eStatus.On;
            else
              fItem.Status = ASystem.eStatus.Unpowered;
          }
          else
            fItem.Status = ASystem.eStatus.Off;
        }
      } // foreach (var fItem in AS)

      foreach (var fItem in AS)
      {
        switch (fItem.Status)
        {
          case ASystem.eStatus.On:
            TryStart(fItem);
            break;
          case ASystem.eStatus.Off:
          case ASystem.eStatus.Unpowered:
            TryStop(fItem);
            break;
          default:
            throw new NotImplementedException();
        }
      } // foreach (var fItem in AS)

    }

    private static void TryStart (ASystem s)
    {
      if (Procs[s] == null)
        StartVoice (s);
    }
    private static void TryStop(ASystem s)
    {
      if (Procs[s] != null)
        StopVoice (s);
    }

    #endregion Private methods

    #region Processes

    private static void StopVoice(ASystem sender)
    {
        System.Diagnostics.Process p = Procs[sender];

      if (p != null)
      {

        if (!p.HasExited)
          p.Kill();

      }

      Procs[sender] = null;

      }

    private static void StartVoice(ASystem sender)
    {
      StopVoice(sender);

      if (!sender.HasVoice)
        return;

      System.Diagnostics.Process process = new System.Diagnostics.Process();
      StringBuilder args = new StringBuilder();
      if (sender.StartVoice != null)
        args.Append("\"" + sender.StartVoice + "\" ");
      if (sender.GoVoice != null)
        args.Append("\"" + sender.GoVoice + "\" ");
      
      process.StartInfo.FileName = "PSSSystemSound.exe";
      process.StartInfo.WorkingDirectory = System.Windows.Forms.Application.StartupPath;
      process.StartInfo.Arguments = args.ToString();
      process.StartInfo.CreateNoWindow = false;
      process.StartInfo.UseShellExecute = false;      
      process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;

      process.Start();

      process.PriorityBoostEnabled = false;
      process.PriorityClass = ProcessPriorityClass.Idle;

      Procs[sender] = process;
    }

    #endregion Processes

  }
}
